/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-03-08     Hao       the first version
 */
#include <hardware/pwm_operate.h>

#include "main.h"

// cubemx里面复制出来的，这里不使用RTThread框架，因为PWM使用中心对齐模式需要修改bsp
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
// 频率25Khz
static void MX_TIM3_Init(void)
{
    TIM_ClockConfigTypeDef sClockSourceConfig = { 0 };
    TIM_MasterConfigTypeDef sMasterConfig = { 0 };
    TIM_OC_InitTypeDef sConfigOC = { 0 };

    htim3.Instance = TIM3;
    htim3.Init.Prescaler = 0;
    htim3.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
    htim3.Init.Period = 1440 - 1;
    htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
    {
        Error_Handler();
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
    {
        Error_Handler();
    }
    if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
    {
        Error_Handler();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
    {
        Error_Handler();
    }
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
    {
        Error_Handler();
    }
    if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
    {
        Error_Handler();
    }
    if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
    {
        Error_Handler();
    }

    HAL_TIM_MspPostInit(&htim3);
}

// 舵机一般PWM周期20ms
static void MX_TIM2_Init(void)
{
    TIM_ClockConfigTypeDef sClockSourceConfig = { 0 };
    TIM_MasterConfigTypeDef sMasterConfig = { 0 };
    TIM_OC_InitTypeDef sConfigOC = { 0 };

    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 720 - 1;
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 2000 - 1;
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
    {
        Error_Handler();
    }
    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
    if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
    {
        Error_Handler();
    }
    if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
    {
        Error_Handler();
    }
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
    sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
    if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
    {
        Error_Handler();
    }
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 0;
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
    if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
    {
        Error_Handler();
    }
    if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
    {
        Error_Handler();
    }

    HAL_TIM_MspPostInit(&htim2);
}

int pwm_operate_init(void)
{
    /* 初始化设备 */
    MX_TIM2_Init();
    MX_TIM3_Init();

    /* 使能设备 */
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);

    /* 默认输出为0 */
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 0);
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, 0);
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0);
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, 0);

    return 0;
}
INIT_APP_EXPORT(pwm_operate_init);

// ch 定时器通道
// duty 占空比，0-1
void motor_pwm_set(uint8_t ch, float duty)
{
    if(ch == 1)
    {
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (uint32_t) (duty * 1440));
    }
    else if(ch == 2)
    {
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, (uint32_t) (duty * 1440));
    }
    else if(ch == 3)
    {
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, (uint32_t) (duty * 1440));
    }
}

// ch 定时器通道，这里AUX1就是通道1，AUX2就是通道2
// duty 占空比，0-1
void aux_pwm_set(uint8_t ch, float duty)
{
    if(ch == 1)
    {
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, (uint32_t) (duty * 2000));
    }
    else if(ch == 2)
    {
        __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, (uint32_t) (duty * 2000));
    }
}

#if 0

void pwm_test(int argc, char**argv)
{
    if (argc < 2)
    {
        return;
    }

    if (!rt_strcmp(argv[1], "00"))
    {
        motor_pwm_set(1, 0);
    }
    if (!rt_strcmp(argv[1], "22"))
    {
        motor_pwm_set(1, 0.2);
    }
    if (!rt_strcmp(argv[1], "44"))
    {
        motor_pwm_set(1, 0.4);
    }
    if (!rt_strcmp(argv[1], "66"))
    {
        motor_pwm_set(1, 0.6);
    }
    if (!rt_strcmp(argv[1], "88"))
    {
        motor_pwm_set(1, 0.8);
    }
    if (!rt_strcmp(argv[1], "10"))
    {
        motor_pwm_set(1, 1);
    }
}
MSH_CMD_EXPORT(pwm_test, pwm test);
#endif
